using System;
using FireStarter.Base;
using FireStarterModeller.BO;
using FireStarterModeller.UI;
using FireStarterModeller.UI.LookupLists;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.BO.Loaders;
using Habanero.Faces.Base;
using NUnit.Framework;

namespace FireStarterModeller.Test.UI
{
    [TestFixture]
    public class TestDMPropertyEditorControl
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            UITestUtils.SetupFixture();
        }


        [SetUp]
        public virtual void SetupTest()
        {
            UITestUtils.SetupTest();
        }

        private static IControlFactory GetControlFactory()
        {
            return GlobalUIRegistry.ControlFactory;
        }

        [Test]
        public void TestMainLayout()
        {
            //---------------Set up test pack-------------------
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());
            //---------------Test Result -----------------------
            Assert.AreEqual(2, dmPropertyEditorControl.Controls.Count);
            //Should have the group box and the details BOEditor Panel    
        }

        [Test]
        public void TestDetailPanelLayout_HasPropertyName()
        {
            //---------------Execute Test ----------------------
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());

            //---------------Test Result --------------------------
            IPanelInfo panelInfo = dmPropertyEditorControl.DetailPanelInfo;
            Assert.IsNotNull(panelInfo);
            PanelInfo.FieldInfoCollection mappers = panelInfo.FieldInfos;
            Assert.IsNotNull(mappers);
            Assert.IsInstanceOf(typeof(ITextBox), mappers["PropertyName"].ControlMapper.Control);
            Assert.IsNotNull(dmPropertyEditorControl.ExtendedPropsPanelInfo);
        }

        [Test]
        public void TestBusinessObjectIsSameAsOneInPanelInfo()
        {
            //---------------Set up test pack-------------------
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());
            //---------------Assert Precondition----------------
            Assert.AreEqual(dmPropertyEditorControl.BusinessObject,
                            dmPropertyEditorControl.DetailPanelInfo.BusinessObject);
            //---------------Execute Test ----------------------
            DMProperty newBO = new DMProperty();
            dmPropertyEditorControl.BusinessObject = newBO;
            //---------------Test Result -----------------------
            Assert.AreSame(newBO, dmPropertyEditorControl.BusinessObject);
            Assert.AreSame(newBO, dmPropertyEditorControl.DetailPanelInfo.BusinessObject);
            Assert.AreSame(newBO, dmPropertyEditorControl.ExtendedPropsPanelInfo.BusinessObject);
        }

        [Ignore("Changing how this works")]
        [Test]
        public void Test_DisplayErrors()
        {
            //---------------Set up test pack-------------------
            DMPropertyEditorControl dmClassEditorControl = new DMPropertyEditorControl(GetControlFactory());
            DMClass newBO = new DMClass();
            dmClassEditorControl.BusinessObject = newBO;
            PanelInfo.FieldInfo fieldInfo = dmClassEditorControl.DetailPanelInfo.FieldInfos["ClassNameBO"];
            //---------------Assert Precondition----------------
            Assert.IsFalse(fieldInfo.ControlMapper.ErrorProvider.GetError(fieldInfo.InputControl).Length > 0);

            //---------------Execute Test ----------------------
            dmClassEditorControl.DisplayErrors();

            //---------------Test Result -----------------------
            Assert.IsTrue(fieldInfo.ControlMapper.ErrorProvider.GetError(fieldInfo.InputControl).Length > 0);
        }

        [Ignore("Changing how this works")]
        [Test]
        public void Test_ClearErrors()
        {
            //---------------Set up test pack-------------------
            DMPropertyEditorControl dmClassEditorControl = new DMPropertyEditorControl(GetControlFactory());
            DMClass newBO = new DMClass();
            dmClassEditorControl.BusinessObject = newBO;
            PanelInfo.FieldInfo fieldInfo = dmClassEditorControl.DetailPanelInfo.FieldInfos["ClassNameBO"];
            dmClassEditorControl.DisplayErrors();

            //---------------Assert Precondition----------------
            Assert.IsTrue(fieldInfo.ControlMapper.ErrorProvider.GetError(fieldInfo.InputControl).Length > 0);

            //---------------Execute Test ----------------------
            dmClassEditorControl.ClearErrors();
            //---------------Test Result -----------------------
            Assert.IsFalse(fieldInfo.ControlMapper.ErrorProvider.GetError(fieldInfo.InputControl).Length > 0);
        }

        [Test]
        public void Test_PropertyTypeComboBox_HasCorrectNoItems()
        {
            //---------------Set up test pack-------------------
            ClassDef.ClassDefs.Clear();
            ClassDef.ClassDefs.Add(new XmlClassDefsLoader(BOBroker.GetClassDefsXml(), new DtdLoader()).LoadClassDefs());
            TestUtilsShared.CreateSavedPropertyTypeInfo();
            TestUtilsShared.CreateSavedPropertyTypeInfo();
            TestUtilsShared.CreateSavedPropertyTypeInfo();
            BusinessObjectCollection<DMPropertyType> propertyTypes =
                BORegistry.DataAccessor.BusinessObjectLoader.GetBusinessObjectCollection<DMPropertyType>("", "");
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());
            IPanelInfo detailPanelInfo = dmPropertyEditorControl.DetailPanelInfo;
            PanelInfo.FieldInfo propertyTypeFieldInfo = detailPanelInfo.FieldInfos["PropertyTypeID"];
            //---------------Assert Precondition----------------
            Assert.IsTrue(propertyTypes.Count > 0);
            //---------------Execute Test ----------------------
            dmPropertyEditorControl.BusinessObject = new DMProperty();
            int noComboItems = ((IExtendedComboBox)propertyTypeFieldInfo.ControlMapper.Control).ComboBox.Items.Count;
            //---------------Test Result -----------------------
            Assert.AreEqual(propertyTypes.Count + 1, noComboItems,
                            "Should have loaded the PropertyTypes into the Combo Box");
        }

        [Test]
        public void Test_SetProperty_ShouldLoadPropertyTypeCombo_WithSolutionPropertyTypes()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            var solution = dmClass.Solution;
            BusinessObjectCollection<DMPropertyType> propertyTypes = solution.PropertyTypes;
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());
            //--------------- Test Preconditions ----------------
            IComboBox propertyTypeCombo = dmPropertyEditorControl.PropertyTypeCombo;
            Assert.AreEqual(0, propertyTypeCombo.Items.Count);
            Assert.IsTrue(propertyTypes.Count > 0);
            //--------------- Execute Test ----------------------
            dmPropertyEditorControl.BusinessObject = dmProperty;
            //--------------- Test Result -----------------------
            Assert.AreEqual(propertyTypes.Count + 1, propertyTypeCombo.Items.Count);
            ComboPair comboPair = (ComboPair)propertyTypeCombo.Items[1];
            object key = comboPair.Value;
            Guid id = new Guid((string)key);
            DMPropertyType foundPropertyType = propertyTypes.Find(id);
            Assert.IsNotNull(foundPropertyType);
        }

        [Test]
        public void Test_SetProperty_ShouldSetPropertyRules()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());
            //--------------- Test Preconditions ----------------
            Assert.AreNotSame(dmProperty, dmPropertyEditorControl.BusinessObject);
            Assert.AreNotSame(dmProperty, dmPropertyEditorControl.PropRuleControl.BusinessObject);
            //--------------- Execute Test ----------------------
            dmPropertyEditorControl.BusinessObject = dmProperty;
            //--------------- Test Result -----------------------
            Assert.AreSame(dmProperty, dmPropertyEditorControl.BusinessObject);
            Assert.AreSame(dmProperty, dmPropertyEditorControl.PropRuleControl.BusinessObject);
        }

        [Test]
        public void Test_SetProperty_ShouldSetLookupListControl()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());
            IGroupBox rulesGroupBox = (IGroupBox)dmPropertyEditorControl.Controls["Property Rules"];
            ITabControl rulesTabControl = (ITabControl)rulesGroupBox.Controls[0];
            ITabPage lookupTabPage = rulesTabControl.TabPages[2];
            LookupTypeSelectorControl lookupTypeSelectorControl = (LookupTypeSelectorControl)lookupTabPage.Controls[0];
            //--------------- Test Preconditions ----------------
            Assert.AreNotSame(dmProperty, lookupTypeSelectorControl.DMProperty);
            //--------------- Execute Test ----------------------
            dmPropertyEditorControl.BusinessObject = dmProperty;
            //--------------- Test Result -----------------------
            Assert.AreSame(dmProperty, lookupTypeSelectorControl.DMProperty);
        }

        [Test]
        public void Test_SetProperty_WhenSetToPreviousProp_ShouldSetPropertyRules()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory()) { BusinessObject = dmProperty };
            DMProperty dmPropertySecond = dmClass.Properties.CreateBusinessObject();
            //--------------- Test Preconditions ----------------
            Assert.AreNotSame(dmPropertySecond, dmPropertyEditorControl.BusinessObject);
            Assert.AreNotSame(dmPropertySecond, dmPropertyEditorControl.PropRuleControl.BusinessObject);
            Assert.AreNotSame(dmPropertySecond, dmPropertyEditorControl.ExtendedPropsPanelInfo.BusinessObject);
            //--------------- Execute Test ----------------------
            dmPropertyEditorControl.BusinessObject = dmPropertySecond;
            //--------------- Test Result -----------------------
            Assert.AreSame(dmPropertySecond, dmPropertyEditorControl.BusinessObject);
            Assert.AreSame(dmPropertySecond, dmPropertyEditorControl.PropRuleControl.BusinessObject);
            Assert.AreSame(dmPropertySecond, dmPropertyEditorControl.ExtendedPropsPanelInfo.BusinessObject);
        }

        [Test]
        public void Test_SetProperty_WhenSetToPreviousProp_ShouldSetLookupList()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory()) { BusinessObject = dmProperty };
            DMProperty dmPropertySecond = dmClass.Properties.CreateBusinessObject();
            IGroupBox rulesGroupBox = (IGroupBox)dmPropertyEditorControl.Controls["Property Rules"];
            ITabControl rulesTabControl = (ITabControl)rulesGroupBox.Controls[0];
            ITabPage lookupTabPage = rulesTabControl.TabPages[2];
            LookupTypeSelectorControl lookupTypeSelectorControl = (LookupTypeSelectorControl)lookupTabPage.Controls[0];

            //--------------- Test Preconditions ----------------
            Assert.AreNotSame(dmPropertySecond, lookupTypeSelectorControl.DMProperty);
            Assert.AreSame(dmProperty, lookupTypeSelectorControl.DMProperty);
            //--------------- Execute Test ----------------------
            dmPropertyEditorControl.BusinessObject = dmPropertySecond;
            //--------------- Test Result -----------------------
            Assert.AreSame(dmPropertySecond, lookupTypeSelectorControl.DMProperty);

        }

        [Test]
        public void Test_ResetProperty_WithDiffSolution_ShouldLoadPropertyTypeCombo_WithSolutionPropertyTypes()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            DMSolution solution = (DMSolution) dmClass.Solution;
            BusinessObjectCollection<DMPropertyType> propertyTypes = solution.PropertyTypes;
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory()) { BusinessObject = dmProperty };
            IComboBox propertyTypeCombo = dmPropertyEditorControl.PropertyTypeCombo;
            //--------------- Test Preconditions ----------------
            Assert.AreEqual(propertyTypes.Count + 1, propertyTypeCombo.Items.Count);
            ComboPair comboPair = (ComboPair)propertyTypeCombo.Items[1];
            object key = comboPair.Value;
            Guid id = new Guid((string)key);
            DMPropertyType foundPropertyType = propertyTypes.Find(id);
            Assert.IsNotNull(foundPropertyType);
            //--------------- Execute Test ----------------------
            DMClass dmClass1 = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty1 = dmClass1.Properties.CreateBusinessObject();
            DMSolution solution1 = (DMSolution) dmClass1.Solution;
            propertyTypes = solution1.PropertyTypes;
            dmPropertyEditorControl.BusinessObject = dmProperty1;
            propertyTypeCombo = dmPropertyEditorControl.PropertyTypeCombo;
            //--------------- Test Result -----------------------
            Assert.AreEqual(propertyTypes.Count + 1, propertyTypeCombo.Items.Count);
            ComboPair comboPair1Reloaded = (ComboPair)propertyTypeCombo.Items[1];
            object keyReloaded = comboPair1Reloaded.Value;
            Guid idReloaded = new Guid((string)keyReloaded);
            DMPropertyType foundPropertyTypeReloaded = propertyTypes.Find(idReloaded);
            Assert.IsNotNull(foundPropertyTypeReloaded);
            Assert.AreNotSame(foundPropertyType, foundPropertyTypeReloaded);
        }

        [Test]
        public void Test_ResetProperty_SameSolution_ShouldNotChangePropertyTypeItems()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();


            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            DMSolution solution = (DMSolution) dmClass.Solution;
            BusinessObjectCollection<DMPropertyType> propertyTypes = solution.PropertyTypes;
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());
            IComboBox propertyTypeCombo = dmPropertyEditorControl.PropertyTypeCombo;
            dmPropertyEditorControl.BusinessObject = dmProperty;
            //--------------- Test Preconditions ----------------
            Assert.AreEqual(propertyTypes.Count + 1, propertyTypeCombo.Items.Count);
            ComboPair comboPair = (ComboPair)propertyTypeCombo.Items[1];
            object key = comboPair.Value;
            Guid id = new Guid((string)key);
            DMPropertyType foundPropertyType = propertyTypes.Find(id);
            Assert.IsNotNull(foundPropertyType);
            //--------------- Execute Test ----------------------
            DMProperty dmProperty2 = dmClass.Properties.CreateBusinessObject();
            dmPropertyEditorControl.BusinessObject = dmProperty2;
            //--------------- Test Result -----------------------
            Assert.AreEqual(propertyTypes.Count + 1, propertyTypeCombo.Items.Count);
            comboPair = (ComboPair)propertyTypeCombo.Items[1];
            key = comboPair.Value;
            id = new Guid((string)key);
            foundPropertyType = propertyTypes.Find(id);
            Assert.IsNotNull(foundPropertyType);
        }

        [Test]
        public void Test_RulesGroupBox_ShouldContainTabControlWithRulesAndLLUp()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());
            IGroupBox rulesGroupBox = (IGroupBox)dmPropertyEditorControl.Controls["Property Rules"];
            //---------------Test Result -----------------------
            Assert.IsInstanceOf(typeof(ITabControl), rulesGroupBox.Controls[0]);
            ITabControl rulesTabControl = (ITabControl)rulesGroupBox.Controls[0];
            Assert.AreEqual(3, rulesTabControl.TabPages.Count);
            ITabPage extendedProps = rulesTabControl.TabPages[0];
            Assert.AreEqual("Extended Props", extendedProps.Name);
            Assert.AreEqual("Extended Props", extendedProps.Text);

            ITabPage rulesTabPage = rulesTabControl.TabPages[1];
            Assert.AreEqual("Prop Rules", rulesTabPage.Name);
            Assert.AreEqual("Prop Rules", rulesTabPage.Text);
            Assert.IsInstanceOf(typeof(DMPropRuleControl), rulesTabPage.Controls[0]);

            ITabPage lookupTabPage = rulesTabControl.TabPages[2];
            Assert.AreEqual("Lookup List", lookupTabPage.Name);
            Assert.AreEqual("Lookup List", lookupTabPage.Text);
            Assert.IsInstanceOf(typeof(LookupTypeSelectorControl), lookupTabPage.Controls[0]);


            
            Assert.IsInstanceOf(typeof(IPanel), extendedProps.Controls[0]);
        }

        [Test]
        public void Test_SetBusinessObject_ShouldSetDMSolution_ForPropertyTypeMapper()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            DMPropertyEditorControl dmPropertyEditorControl = new DMPropertyEditorControl(GetControlFactory());
            PanelInfo.FieldInfo propertyTypeFieldInfo = dmPropertyEditorControl.PropertyTypeFieldInfo;
            //---------------Assert Precondition----------------
            Assert.IsInstanceOf(typeof(PropertyTypeMapper), propertyTypeFieldInfo.ControlMapper);
            PropertyTypeMapper propertyTypeMapper = (PropertyTypeMapper)propertyTypeFieldInfo.ControlMapper;
            Assert.IsNull(propertyTypeMapper.DMSolution);
            //---------------Execute Test ----------------------
            dmPropertyEditorControl.BusinessObject = dmProperty;
            //---------------Test Result -----------------------
            Assert.IsNotNull(propertyTypeMapper.DMSolution);
            Assert.AreSame(dmClass.Solution, propertyTypeMapper.DMSolution);
        }
    }
}